#include <iostream>
using namespace std;


/*—————————— 1.只能在堆上创建对象的类 ————————*/
 // ——————方案一
//class HeapOnly
//{
//public:
//	static HeapOnly* CreateObject()
//	{
//		return new HeapOnly;
//	}
//private:
//	HeapOnly() {};
//	HeapOnly(const HeapOnly&) = delete;
//};
//
//
//int main()
//{
//	HeapOnly H;
//	HeapOnly* p = HeapOnly::CreateObject();
//	return 0;
//}

//// 方案二
//class HeapOnly
//{
//public:
//	//方案1 
//	static void Destroy(HeapOnly* hp)
//	{
//		delete hp;
//	}
//	//方案2
//	void Destroy()
//	{
//		delete this;
//	}
//private:
//	~HeapOnly() {};
//};
//
//
//int main()
//{
//	//HeapOnly H; 调不到析构函数，无法创建
//	//静态成员函数释放
//	HeapOnly* hp1 = new HeapOnly;
//	HeapOnly::Destroy(hp1);
//	//普通成员函数释放
//	HeapOnly* hp2 = new HeapOnly;
//	hp2->Destroy(); //手动释放
//
//
//	return 0;
//}
//
/* ———————————— 1. 构造私有化 ——————————*/
//class HeapOnly
//{
//public:
//	//HeapOnly* CreatrObj()
//	static HeapOnly* CreatrObj() //需要用静态的
//	{
//		return new HeapOnly;
//	}
//
//	//封死拷贝构造和赋值
//	HeapOnly(const HeapOnly&) = delete;
//	HeapOnly& operator = (const HeapOnly&) = delete;
//
//private:
//	HeapOnly()
//	{}
//};
// 
//
//
//int main()
//{
//	//static HeapOnly hp0;
//	//HeapOnly hp1;
//	//HeapOnly* hp2 = new HeapOnly;
//
//	HeapOnly* hp3 = HeapOnly::CreatrObj();
//	HeapOnly hp4(*hp3);
//
//	return 0;
//}


///* ———————————— 2. 析构私有化 ——————————*/
//class HeapOnly
//{
//public:
//	void Destroy() 
//	{
//		delete this;
//	}
//
//private:
//	// 析构函数私有化
//	~HeapOnly()
//	{}
//};
// 
//int main()
//{
//	HeapOnly* hp1 = new HeapOnly;
//	HeapOnly hp2(*hp1);
//
//
//	system("pause");
//
//	return 0;
//}






/* ——————————3.只能在栈上创建对象的类 ————————*/
//C++98
//class StackOnly
//{
//public:
//	static StackOnly CreateObj()
//	{
//		return StackOnly();
//	}
//
//	// 封死拷贝构造
//	//StackOnly(const StackOnly& s) = delete; 
//	
//	// 禁掉operator new
//	void* operator new(size_t size) = delete;
//	void operator delete(void* p) = delete;
//
//private:
//	StackOnly()
//		:_a(0)
//	{}
//private:
//	int _a;
//};
//
//int main()
//{
//	// 1.由于构造私有化，无法直接构造
//	//static StackOnly s1;
//	//StackOnly s2;
//	//StackOnly* s3 = new StackOnly;
//
//	// 2.在栈上创建对象，如果封死拷贝构造，下面这个也会禁掉，因此下面我们都不封拷贝构造
//	StackOnly s4 = StackOnly::CreateObj();
//
//	// 3. 禁掉operator new可以把下面用new 调用拷贝构造申请对象给禁掉
//	StackOnly* s5 = new StackOnly(s4); //拷贝构造
//
//	// 4.由于拷贝构造没封，即使封死了operator new，也可以调用
//	static StackOnly s6(s4); // 静态区
//
//	return 0;
//}


// C++11
//// 由于仍然是没有严格的封死，因此我们还是得封拷贝构造
//// 但是导致上面之前得都走不通
//// 由于我们这里实现了拷贝构造，那么这里就不会默认生成移动构造了
//class StackOnly
//{
//public:
//	static StackOnly CreateObj()
//	{
//		return StackOnly();
//	}
//
//	// 封死拷贝构造
//	StackOnly(const StackOnly& s) = delete; 
//	
//	// 提供移动构造
//	StackOnly(StackOnly&& s) 
//	{}
//
//private:
//	StackOnly()
//		:_a(0)
//	{}
//private:
//	int _a;
//};
//
//int main()
//{
//	// 1.由于构造私有化，无法直接构造
//	//static StackOnly s1;
//	//StackOnly s2;
//	//StackOnly* s3 = new StackOnly;
//
//	// 2.拷贝构造封死，然后再调用移动构造，就可以彻底封死了
//	StackOnly s4 = StackOnly::CreateObj();
//	//StackOnly* s5 = new StackOnly(s4); 
//	//static StackOnly s6(s4); 
//
//	// 3.漏洞
//	static StackOnly s7(move(s4));  //移动构造
//	StackOnly* s8 = new StackOnly(move(s4));
//
//	return 0;
//}




///*—————— 不能被继承的类 ——————*/
//class NonInherit
//{
//public:
//	static NonInherit GetInstance()
//	{
//		return NonInherit();
//	}
//private:
//	NonInherit()
//	{}
//};
//
//class A  final
//{
//	// ....
//};


 
 
 
//main函数之前创建出来的就是饿汉
// 单例：全局只有唯一实例对象
///*——-------—————— 饿汉模式 ————————————*/ 
// 优点：简单
// 缺点：
//	1、多个饿汉模式的单例，某个对象初始化内容较多(读文件)，会导致程序启动慢
//	2、A和B两个饿汉，对象初始化存在依赖关系，要求A先初始化，B再初始化，饿汉无法保证

//class InfoMgr
//{
//public:
//	static InfoMgr& GetInstance()
//	{
//		return _ins;
//	}
//
//	void Print()
//	{
//		cout << _ip << endl;
//		cout << _port << endl;
//		cout << _buffSize << endl;
//	}
//private:
//	InfoMgr(const InfoMgr&) = delete;
//	InfoMgr& operator=(const InfoMgr&) = delete;
//
//	InfoMgr()
//	{
//		cout << "InfoMgr()" << endl;
//	}
//private:
//	string _ip = "127.0.0.1";
//	int _port = 80;
//	size_t _buffSize = 1024 * 1024;
//	//...
//
//	static InfoMgr _ins;
//};
//InfoMgr InfoMgr::_ins; // 在程序入口之前就完成单例对象的初始化
//
//int main()
//{
//	cout << endl;
//	InfoMgr::GetInstance().Print();
//	//InfoMgr copy(InfoMgr::GetInstance());
//	cout << endl;
//	InfoMgr::GetInstance().Print();
//
//	cout << endl;
//	cout << &InfoMgr::GetInstance() << endl;
//	cout << &InfoMgr::GetInstance() << endl;
//
//	return 0;
//}




///*—————————— 懒汉模式 ———————— */
// 懒汉
// 优点：第一次使用实例对象时，创建对象。进程启动无负载。多个单例实例启动顺序自由控制。
// 缺点：复杂

////写法一：
//class InfoMgr
//{
//public:
//	// 第一次调用时再去创建单例对象
//	// 线程安全的风险（暂时没学）
//	static InfoMgr& GetInstance()
//	{
//		if (_pins == nullptr) //第一次调用刚好是空
//		{
//			_pins = new InfoMgr;
//		}
//		return *_pins;
//	}
//
//	void Print()
//	{
//		cout << _ip << endl;
//		cout << _port << endl;
//		cout << _buffSize << endl;
//	}
//
//	static void DelInstance() //主动释放单例
//	{
//		delete _pins;
//		_pins = nullptr;
//	}
//
//private:
//	InfoMgr(const InfoMgr&) = delete;
//	InfoMgr& operator=(const InfoMgr&) = delete;
//
//	InfoMgr()
//	{
//		cout << "InfoMgr()" << endl;
//	}
//private:
//	string _ip = "127.0.0.1";
//	int _port = 80;
//	size_t _buffSize = 1024 * 1024;
//	//...
//
//	static InfoMgr* _pins;
//};


//懒汉模式更简单的写法，C++11之后更加推荐
class InfoMgr
{
public:
	// 第一次调用时再去创建单例对象
	// 线程安全的风险（暂时没学）
	static InfoMgr& GetInstance()
	{
		//C++11之后才是这样
		static InfoMgr ins; //创建一个局部的静态，因为局部的静态是在创建的时候初始化
		return ins;
	}

	void Print()
	{
		cout << _ip << endl;
		cout << _port << endl;
		cout << _buffSize << endl;
	}

private:
	InfoMgr(const InfoMgr&) = delete;
	InfoMgr& operator=(const InfoMgr&) = delete;

	InfoMgr()
	{
		cout << "InfoMgr()" << endl;
	}
private:
	string _ip = "127.0.0.1";
	int _port = 80;
	size_t _buffSize = 1024 * 1024;
	//...

	static InfoMgr* _pins;
};



InfoMgr* InfoMgr::_pins = nullptr; //设计为指针

int main()
{
	cout << endl;
	InfoMgr::GetInstance().Print();

	cout << endl;
	InfoMgr::GetInstance().Print();

	cout << endl;
	//查看多次调用时对象地址
	cout << &InfoMgr::GetInstance() << endl;
	cout << &InfoMgr::GetInstance() << endl;

	return 0;
}